/*
 * MonsterSprite.java
 *
 * Created on January 20, 2008, 9:05 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package wisp.game;
//JFC
import com.golden.gamedev.object.sprite.AdvanceSprite;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.net.*;

//Wisp
import wisp.dataObjects.*;
import wisp.dataObjects.Monster;
import wisp.dataObjects.MonsterType;
import wisp.dataObjects.Statistics;
import wisp.dataObjects.WispCharacter;


// GTGE
import com.golden.gamedev.*;
import com.golden.gamedev.object.*;
import com.golden.gamedev.engine.BaseLoader;
import com.golden.gamedev.GameLoader;
import com.golden.gamedev.object.sprite.VolatileSprite;
import com.golden.gamedev.Game;

import com.golden.gamedev.object.background.ImageBackground;
/**
 *
 * @author Solomon See
 */
public class MonsterSprite extends CharacterSprite {
   
	private Timer monsterTimer;
    private String type;
    private Game maingame;
    
    //
    private boolean hasTarget;
    private boolean attackMode;
    private CharacterSprite target;
    
    //
    private double range;
    private MonsterType monsterData;
    private Monster monsterData2;
    
    /** Creates a new instance of MonsterSprite */
    public MonsterSprite(String name, MainGame game, BufferedImage[] images, double x, double y, Game g) {
        super(name, "MONSTER", game,images,x,y,false);
       
        initObject();
        initStats(monsterData.getMHP(),monsterData.getMHP(),0,0,500);
       // initStats(120,120,60,60,500);
        range = 150;
        //
        this.setName("Wicked Wisp");
        setSelectable(true);
        
        int atktimer = ((Double)this.getStatistics().getARate()).intValue() * 1000;

        //creation message
        System.out.println("Creating: " + this.getName() + " [ " + this.getMonsterData().getMHP() + "HP :: " + this.getMonsterData().getEGained() + "exp :: " +  this.getStatistics().getAtk() + "atk ]");
       
        monsterTimer = new Timer(atktimer);
        type = "MONSTER";
        
        //
        maingame = g;
    }
    
    
/*    public void setActive(boolean b) {
        super.setActive(b);
        monsterTimer.setActive(b);
    }*/
    public int[] getUpImages() {
        return new int[] {0};
    }
    public int[] getDownImages(){
        return new int[] {0};
    }
    public int[] getLeftImages(){
        return new int[] {0};
    }
    public int[] getRightImages(){
        return new int[] {0};
    }  
    
    //ADDED//
    public int[] getUpFlinch(){
    	return new int[]{1};
    }
    
    public int[] getDownFlinch(){
    	return new int[]{1};    
    }
    
    public int[] getLeftFlinch(){
    	return new int[]{1};
    }
    
    public int[] getRightFlinch(){
    	return new int[]{1};
    }
    //END ADDED//
    
    ///////////added - for buff <DUMMY since not needed>
    public int[] getUpBuffed(){
    	return new int[]{2};
    }
    public int[] getDownBuffed(){
    	return new int[]{2};
    }
    public int[] getLeftBuffed(){
    	return new int[]{2};
    }
    public int[] getRightBuffed(){
    	return new int[]{2};
    }
    ///////////////////
    
    protected void randomMove() {
        int dispx = getGame().getRandom(-50,50);
        int dispy = getGame().getRandom(-50,50);
        setMoveLocation(getMiddleX()+dispx, getMiddleY()+dispy);
    }
    public void update(long elapsedTime) {
    	if(hasTarget){
        	//following checks what action player wants to perform
        	if(attackMode){
        			if ( isDead() == false && target.isDead() == false)
        			{	//System.out.println ("lalalalala");
        				if(inRange(target, this))
        				{	//System.out.println ("lololololol");
        					commenceAttack(elapsedTime);
        					if(target!=null)
        	        			setMoveLocation(target.getScreenX(), target.getScreenY());
        				}
        				else
        				{	//System.out.println("[" + this.getName() + "] : User has gone out of attack range\n");
        					//this.hasTarget = false;
        					//resetMode();
        					setMoveLocation(target.getX(), target.getY());
        					
        				}	
        				move(elapsedTime);
        			}
        		
        			else
        			{
        				resetMode();
        				this.hasTarget = false;
        			}
        	}
        }
    	else if(monsterTimer.action(elapsedTime) && attackMode == false) {
            randomMove();
        }
        else 
        	move(elapsedTime);
    	
        super.update(elapsedTime);
    }
    
    public boolean inRange(CharacterSprite cs, CharacterSprite self){
    	boolean value;
    	double xdistance = 0;
    	double ydistance = 0;
    	
    	if(cs.getScreenX() > self.getScreenX()){
    		xdistance = cs.getScreenX() - self.getScreenX();
    	}
    	else
    		xdistance = self.getScreenX() - cs.getScreenX();
    	
    	if(cs.getScreenY() > self.getScreenY()){
    		ydistance = cs.getScreenY() - self.getScreenY();
    	}
    	else
    		ydistance = self.getScreenY() - cs.getScreenY();
    	
    	//System.out.println(">>>> RANGE DIST : X>" + xdistance + " Y>" + ydistance + "\n\n");
    	
    	if(xdistance > this.range || ydistance > this.range){
    		value = false;
    	}
    	else
    		value = true;
    	
    	return value;
    }
    
	public void commenceAttack(long elapsedTime) 
	{
		//System.out.println ("hohohohohohoho");
		//checkForSkillUsed() skills must interrupt normal attack if used so its first
		if ( monsterTimer.action(elapsedTime)) //okay to attack
		{
			//System.out.println ("hihihihihih");
			performNormalAttack();
		}
	}

	public void performNormalAttack() {
		
		double damage = 0;
		
		boolean attackFlag = attackIsSuccessful ();
		
		System.out.println("[COMBAT] " + this.getName() + " attacks " + target.getName());
		
		if ( attackFlag == true)
		{

			damage = this.computeDamage(attackFlag);
			target.hit(this, damage);	
			
			if(target!=null)
				System.out.println("[COMBAT] " + target.getName() + " takes " + damage + " dmg");
		}
    	else
    	{	System.out.println("[COMBAT] " + this.getName() + " misses");
    		target.hit(this,0);
    	}
		
	}
		

	private double computeDamage(boolean value) {
		WispCharacter wispcharacter = (WispCharacter)target.getData();
		return getActions().computeDamageM(monsterData2, this.getStatistics(), target.getStatistics(), wispcharacter, value);
	}

	private boolean attackIsSuccessful() {
		//System.out.println ("lalalalala");
		if (getActions().getSuccessACC(getStatistics().getARate()) == true)
			return true;
		else
			return false;
	}
    
    public void selected() {
    	//System.out.println("A Monster was selected.");
    	getGame().bsInput.refresh();
    }
    
    public void clicked() {
	
    	//if (isSelected())
    	//System.out.println("clicked.");	
}

    public void deselected() {
    	//System.out.println("A Monster was deselected.");
    }
    
    public void resetMode()
    {
    	attackMode = false;
    	hasTarget = false;
        target = null;
        setDamagedRecieved(-1);
        this.setFlinch(false);
    }
    
    public Object getData()
    {
    	return getMonsterData2();
    }
    
    public void setMonsterData2(Monster monsterData2) {
    	this.monsterData2 = monsterData2;
    }
    
    public Monster getMonsterData2() {
    	return monsterData2;
    }
    
    @Override
    public void initObject() {
   // 	monsterData = new MonsterType ("Squiggly", "Sallela", "description", 80, 40, 1);
    	monsterData = new MonsterType();
    	monsterData.viewTInfo("Wicked Wisp");
    	monsterData2 = new Monster(monsterData.getMHP(), 0, 0, 500, 500, 0, "Wicked Wisp");
    	setStatistics(new Statistics ("Squiggly",10, 2, 1 , 10, 1, 2, 1 , 2, 2, 1, 1, 1, 1, 1, 1, 1, 1));
    //	Statistics stats = new Statistics();
    //	stats.viewStat("Wicked Wisp");
   
	  //  setStatistics(stats);
    	
    }
    
    public void hit(CharacterSprite cs, double damage)
    {
    	//this means the monster must realize its being attacked 
    	//System.out.println ("pumasok sa hit ni monster!");
    	if (attackMode == false)
    	{	
    		attackMode = true;
    		target = cs;
    		hasTarget = true;
    		//System.out.println ("dapat naset ung hasTarget and attackMode!!!");
    	}
    	
		///FOR DAMAGE DISPLAY
		this.setBeingDamaged(true);
		this.setDamagedRecieved(((Double)damage).intValue());
		
		this.getGame().getParticleGroup().add(new HitSprite(this.getGame().getImages("IMAGES/Sprites/hit.png", 3, 1), getX()+(getWidth()/2), getY()+(getHeight()/2)));
		///FLINCH
		this.setFlinch(true);
		//

    	this.setCurrentHP(this.getCurrentHP() - (new Double(damage).intValue()));
    	//	
    	this.getHp_bar().setCurrValue(new Double((new Double(this.getCurrentHP()).doubleValue() / new Double(this.getMaxHP()).doubleValue()) * 100).intValue());
    	//
    	//System.out.println ("Monster current HP is: " + this.getCurrentHP());
    	// check if dead:
    	//    true : call cs.gainEXP() --> gainEXP is in charge of checking if player has leveled
    	if (isDead() == true)
    	{
    		this.getGame().getCorpseGroup().add(new Corpse("Cyclops",getGame(), (this.getGame().getImages("IMAGES/Sprites/corpse.png", 1, 1)), getX(), getY()));
    		
    		this.setActive(false); ///vanish monster!! pero dapat may animate death x.x
    		target.resetMode();
    		System.out.println("[COMBAT] " + this.getName() + " is dead!");
    		PlayerSprite player = (PlayerSprite)target;
    		player.checkIfLevelUp(this.getExpValue());
    	}
    	
    	//call animateHit ()
    	// call animateDamage()
    }
    
    public int getExpValue()
    {
    	return getMonsterData().getEGained();
    }
	public MonsterType getMonsterData() {
		return monsterData;
	}
	public void setMonsterData(MonsterType monsterData) {
		this.monsterData = monsterData;
	}
}
